#pragma once

#include <AVUIAnimatable.h>
#include <AVUIMILUtilities.h>
#include <AVUIMatrix3D.h>
#include <AVUIRect3D.h>
#include <AVUIGeneralTransform.h>

namespace AVUI {
class PointCollection;
class Point3DCollection;
class Int32Collection;
class GeneralTransform3D;

// REVIEW !! THIS SHOULD BE BASED ON FREEZABLE, REWRITE ONCE COMPLETE!
class Transform;

/// <summary>Provides 2-D to 3-D transformation support.</summary>
class GeneralTransform2DTo3D : public Animatable
{
public:
    DECLARE_ELEMENT(GeneralTransform2DTo3D, Animatable);

#pragma region Public Methods

/// <summary>Transforms the specified point and returns the result.</summary>
/// <returns>The result of transforming <paramref name="point" />.</returns>
/// <param name="point">The point to transform.</param>
/// <exception cref="T:System.InvalidOperationException">The transform did not succeed.</exception>
    Point3D Transform(const Point& point)
    {
        Point3D pointd;
        if (!TryTransform(point, &pointd))
        {
            LibraryThrowException(object_allocate<InvalidOperationException>("General transform failed."));
        }
        return pointd;
    }

    /// <summary>Attempts to transform the specified point and returns a value that indicates whether the transformation was successful.</summary>
    /// <returns>true if <paramref name="inPoint" /> was transformed; otherwise, false.</returns>
    /// <param name="inPoint">The point to transform.</param>
    /// <param name="result">The result of transforming <paramref name="inPoint" />.</param>
    bool TryTransform(const Point& inPoint, Point3D* pResult);

#pragma endregion Public Methods

protected:

#pragma region Protected Methods
    virtual TRefCountedPtr<Freezable> CreateInstanceCore() AVUI_OVERRIDE { return object_allocate<GeneralTransform2DTo3D>().get_Ptr(); }
#pragma endregion Protected Methods

public:

#pragma region Internal Methods

    GeneralTransform2DTo3D(GeneralTransform* pTransform2D, Viewport2DVisual3D* pContainingVisual3D, GeneralTransform3D* pTransform3D) { }
    GeneralTransform2DTo3D() { }

#pragma endregion Internal Methods

private:

#pragma region Private Fields

    Rect m_childBounds;
    TRefCountedPtr<Point3DCollection> m_pPositions;
    TRefCountedPtr<PointCollection> m_pTextureCoords;
    TRefCountedPtr<GeneralTransform> m_pTransform2D;
    TRefCountedPtr<GeneralTransform3D> m_pTransform3D;
    TRefCountedPtr<Int32Collection> m_pTriIndices;

#pragma endregion Private Fields

};


}; // namespace AVUI
